#include "construtorIndice.h"
#include "ordenacao.h"
#include "persistencia.h"
#include <string.h>

uint64_t obtemPosicaoAtual(FILE *file){
  return ftell(file);
}

ChavePrimaria constroiChavePrimaria(RegAluno regImportacao, uint64_t byteOffset){
  ChavePrimaria chavePrimaria;
  chavePrimaria.inscricao = regImportacao.inscricao;
  chavePrimaria.byteOffset = byteOffset;
  return chavePrimaria;
}

ChaveSecundaria constroiChaveSegundariaNome(RegAluno regImportacao){
  ChaveSecundaria chaveSecundaria;
  chaveSecundaria.nomeOuCurso = regImportacao.nome;
  chaveSecundaria.ref = NULL;  
  return chaveSecundaria;
}

int calculaTamRegistroBanco(RegAluno registro){
  // nome, curso, inscricao, nota, | e quebralinha
  return strlen(registro.nome) + strlen(registro.curso) + 6 + 5 + 5;
}

void serializaRegistroImportacao(RegAluno registro, char *regSerializado){
  int tamanho = calculaTamRegistroBanco(registro);
  //0000-> tamanho, 000000-> inscricao, nome, curso, 00000->nota  
  sprintf(regSerializado,"%04d|%06d|%s|%s|%05d\n",tamanho,registro.inscricao,registro.nome,registro.curso,registro.nota);  
}

void serializaChavePrimaria(ChavePrimaria chavePrimaria, char *chaveSerializada){
  // 000000-> inscricao, 0000000000 -> byteoffset
  sprintf(chaveSerializada,"%06d|%010d|1\n",chavePrimaria.inscricao,chavePrimaria.byteOffset);
}

void serializaChaveSegundaria(ChaveSecundaria chaveSecundaria, char *chaveSerializada){
  int distanciaProx = distanciaElementoAteComecoListaInvertida(chaveSecundaria.ref);
  sprintf(chaveSerializada,"%s|%06d\n", chaveSecundaria.nomeOuCurso, distanciaProx*14);
}

void serializaElemento(ElementoListaInvertida elemento, int distanciaProx, char *elementoSerializado){
  sprintf(elementoSerializado,"%06d|%06d\n", elemento.inscricao, distanciaProx != -1 ? distanciaProx*14 : distanciaProx);  
}

void importar(FILE *fileImportacao, ArquivosPersistencia *arquivos){
  char buffer[1000];
  
  while(!feof(fileImportacao)){
    fgets(buffer, sizeof(buffer), fileImportacao);    
    RegAluno reg = convertLinhaToRegistro(buffer);    
    
    int posicaoBanco = obtemPosicaoAtual(arquivos->fileBanco);
    gravaRegistroArgBanco(reg,arquivos->fileBanco);
    
    ChavePrimaria chavePrimaria = constroiChavePrimaria(reg,posicaoBanco);
    inserirChavePrimariaLista(chavePrimaria);
    
    insereChaveSecundaria(reg);
    
    limpaRegistroArquivoImportacao(&reg);
  }  
  
  
  gravarListaPrimariaArq(inicioListaInscricao,arquivos);  
  gravarListaInvertidaArq(inicioListaInvertida,arquivos);
  gravarListaSegundariaNomeArq(inicioListaNome,arquivos);
  
}

void insereChaveSecundaria(RegAluno reg){
    ChaveSecundaria *chaveSecundariaNomeEncontrada = buscaChaveSecundariaNome(reg.nome);
    
    if(chaveSecundariaNomeEncontrada != NULL){
      inserirListaInvertida(chaveSecundariaNomeEncontrada,reg);
    } else {
      ChaveSecundaria *chaveSecundaria = inserirChaveSecundariaNomeLista(reg);
      inserirListaInvertida(chaveSecundaria,reg);
    }
        
}
